#pragma once
#include<iostream>
#include<vector>
using namespace std;

namespace sqy
{
    template<size_t N>
    class bit_set
    {
    public:
        bit_set()
        {
            _bits.resize(N/8+1,0);
        }
        void set(size_t x)
        {
            size_t index = x / 8;
            size_t i = x % 8;
            _bits[index] |= (1 << i);
        }
        void reset(size_t x)
        {
            size_t index = x / 8;
            size_t i = x % 8;
            _bits[index] &= ~(1 << i);
        }
        bool test(size_t x)
        {
            size_t index = x / 8;
            size_t i = x % 8;
            return _bits[index] & (1 << i);
        }
    
    private:
        vector<char> _bits;      
    };

    template<size_t N>
    class two_bit_set
    {
    public:
        void set(size_t x)
        {
            bool inset1 = _bs1.test(x);
            bool inset2 = _bs2.test(x);

            if(inset1 == false && inset2 == false)
            {
                _bs2.set(x);
            }
            else if(inset1 == false && inset2 == true)
            {
                _bs1.set(x);
                _bs2.reset(x);
            }
        }
        void print_once_num()
        {
            for(size_t i = 0; i < N; i++)
            {
                if(_bs1.test(i) == false && _bs2.test(i) == true)
                {
                     cout<< i << endl;
                }
            }
        }

    private:
        bit_set<N>_bs1;
        bit_set<N>_bs2;
    };
    //void Test_set()
    //{
    //    bit_set<100>s;
    //    s.set(8);
    //    s.set(20);
    //    s.set(9);

    //    cout<< s.test(8)<<endl;
    //    cout<< s.test(9)<<endl;
    //    cout<< s.test(20)<<endl;
    //    s.reset(8); 
    //    s.reset(20); 
    //    s.reset(9); 

    //    cout<< s.test(8)<<endl;
    //    cout<< s.test(9)<<endl;
    //    cout<< s.test(20)<<endl;
    //}
    void Test_set2()
    {
        int a[] = {3,4,5,6,2,4,3,5,5,5,5,6,3,9};
        two_bit_set<100>s;
        for(auto e : a)
        {
            s.set(e);
        }
        s.print_once_num();
    }
}
